/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package aiaudio.processing.split.mappers;

import aiaudio.processing.base.mapreduce.CoordinateDoubleValueKey;
import aiaudio.Application;
import aiaudio.database.tables.RatingsMatrixTable;
import java.io.IOException;
import java.util.Map;
import java.util.NavigableMap;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.TableMapper;
import org.apache.hadoop.hbase.util.Bytes;

/**
 *
 * @author nastya
 */
public class TestSetExtractorMapper extends TableMapper<ImmutableBytesWritable, CoordinateDoubleValueKey> {

    public static final String COLLECTED_DATA_SET_NAME = "collectedDataSetName";
    HTable dataSet;

    @Override
    protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, InterruptedException {
        byte[] artist = key.get();
        if (RatingsMatrixTable.isDefaultValue(artist)) {
            copy(value, artist, context, false);
        } else {
            copy(value, artist, context, true);
        }
    }

    protected void copy(Result value, byte[] artist, Context context, boolean checkExists) throws IOException, InterruptedException {
        NavigableMap<byte[], byte[]> familyMap = RatingsMatrixTable.getUsers(value);
        for (Map.Entry<byte[], byte[]> entry : familyMap.entrySet()) {
            byte[] user = entry.getKey();
            byte[] listenCount = entry.getValue();
            if (!checkExists || !existsInDataSet(artist, user)) {
                context.write(new ImmutableBytesWritable(artist), new CoordinateDoubleValueKey(Bytes.toDouble(listenCount), user));
            }
        }
    }

    @Override
    protected void setup(Context context) throws IOException, InterruptedException {
        super.setup(context);
        String tableName = context.getConfiguration().get(COLLECTED_DATA_SET_NAME);
        dataSet = Application.database().getByName(tableName).getTable();
    }

    private boolean existsInDataSet(byte[] artist, byte[] user) throws IOException {
        return RatingsMatrixTable.existsInDataSet(dataSet, user, artist);
    }
}
